package com.ykq.system.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ykq.system.vo.CommonResult;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;

/**
 * @program: qy151-springboot-vue
 * @description:
 * @author: 闫克起2
 * @create: 2022-08-09 09:31
 **/
//如果类没有交于spring容器来管理 那么该类中得属性也不能让spring帮你注入
public class LoginFilter extends FormAuthenticationFilter {

    private RedisTemplate redisTemplate;  //LoginFilter必须交于spring容器来管理。

    public LoginFilter(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    //当登录成功后执行得方法，如果该方法返回false，则执行onAccessDenied
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        HttpServletRequest req = (HttpServletRequest) request;
        //1.请求方式是否为OPTIONS
        String method = req.getMethod();
        if(method!=null && method.equals("OPTIONS")){
            return true;
        }

        //2.判断请求头是否有token值
        String token = req.getHeader("token");
        if(token!=null && redisTemplate.hasKey(token)){
            return true;
        }
        return false;
    }

    //未登录时调用该方法? 为什么进入没有登录方法:
    // --->第一个请求是OPTIONS,没有携带token  第二个因为前端和后端不是用得同一个session.默认shiro以sessionId为是否登录得标准
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();

        CommonResult commonResult = new CommonResult(4001,"未登录",null);
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(commonResult);
        writer.print(json);

        writer.flush();
        writer.close();
        return false;
    }
}
